import math
import random as r
import time

import matplotlib.pyplot as plt
import numpy as np
# 开始温度
T = 2000
# 退火步长，每次温度降低 1%
dT = 0.99
# 当温度低于eps时，退出该算法
eps = 1e-14

left = -5
right = 0

def rastrigin(x):
    A = 10
    return A + x**2 - A * np.cos(2 * np.pi * x)


# 创建一个空的图表
plt.figure()
plt.xlabel('X')
plt.ylabel('Y')
plt.title('Simulated Annealing')

# 在给定范围内生成 x 值
x_range = np.linspace(left, right, 400)
y_range = rastrigin(x_range)
plt.plot(x_range, y_range, label='Rastrigin Function')  # 绘制函数图像
plt.legend()

# 原始值
x = r.uniform(left, right)
y = rastrigin(x)
# plt.plot(x, y, 'ro')  # 在图上绘制初始点
index = 0
while T > eps:
    index = index + 1
    # 温度越高移动的越快
    dx = x + r.uniform(-1.5,1.5) * T
    # 产生的新解不在定义域，则重新生成
    while dx < left or  dx > right:
        dx = x + r.uniform(-1.5, 1.5) * T

    # 求出新的dx的解
    dy = rastrigin(dx)

    # 该值为好值，应该保留
    if dy > y:
        y = dy
        x = dx
    # 如果不是好值，也有一定概率保留
    # e^(df/kT)  其中df = - | f(x0) - f(x1) |, k=1 ， T为温度
    else:
        # 生成随机数（0  -  1）
        seek = r.uniform(0,1)
        # 计算概率
        DF = - math.fabs(rastrigin(x) - rastrigin(dx))
        r1 = math.exp(DF / T)
        if seek < r1:
            x = dx
        # 在图上绘制每次迭代的点，并使用plt.pause()函数放慢速度
    plt.plot(x_range, y_range, label='Rastrigin Function')
    plt.plot(x, y, 'ro')
    time.sleep(0.1)  # 等待0.1秒，以便观察每次迭代的点
    print("x = ",x,",y=",y)
    T = T * dT
    plt.show()



# ========================
#
#
# import math
# import random as r
# import time
#
# import matplotlib.pyplot as plt
# import numpy as np
# # 开始温度
# T = 2000
# # 退火步长，每次温度降低 1%
# dT = 0.95
# # 当温度低于eps时，退出该算法
# eps = 1e-14
#
# left = -3
# right = 0
#
# def rastrigin(x):
#     A = 10
#     return A + x**2 - A * np.cos(2 * np.pi * x)
#
#
#
# # 在给定范围内生成 x 值
# x_range = np.linspace(left, right, 400)
# y_range = rastrigin(x_range)
#
# plt.ion()
# fig,ax = plt.subplots()
# lines, = ax.plot([],[])
# ax.set_autoscaley_on(True)
# ax.grid()
#
# # 原始值
# x = r.uniform(left, right)
# y = rastrigin(x)

#
# while T > eps:
#     # 温度越高移动的越快
#     dx = x + r.uniform(-1.5,1.5) * T
#     # 产生的新解不在定义域，则重新生成
#     while dx < left or  dx > right:
#         dx = x + r.uniform(-1.5, 1.5) * T
#
#     # 求出新的dx的解
#     dy = rastrigin(dx)
#
#     # 该值为好值，应该保留
#     if dy > y:
#         y = dy
#         x = dx
#     # 如果不是好值，也有一定概率保留
#     # e^(df/kT)  其中df = - | f(x0) - f(x1) |, k=1 ， T为温度
#     else:
#         # 生成随机数（0  -  1）
#         seek = r.uniform(0,1)
#         # 计算概率
#         DF = - math.fabs(rastrigin(x) - rastrigin(dx))
#         r1 = math.exp(DF / T)
#         if seek < r1:
#             y = dy
#             x = dx
#     lines.set_xdata(x)
#     lines.set_ydata(y)
#
#     ax.relim()
#     ax.autoscale_view()
#
#     fig.canvas.draw()
#     fig.canvas.flush_events()
#     time.sleep(0.1)  # 等待0.1秒，以便观察每次迭代的点
#     print("x = ",x,",y=",y)
#     T = T * dT
#     plt.show()
#
